import gradio as gr
import os
from openai import OpenAI
import json
import uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional

# --- 1. 配置部分 ---
# 百度AI配置（生产环境建议用环境变量存储密钥）
BAIDU_API_KEY = os.environ.get("BAIDU_API_KEY", "xxx")  # 替换为您的实际API Key
BAIDU_BASE_URL = "https://aistudio.baidu.com/llm/lmapi/v3"
MODEL_NAME = "ernie-4.5-turbo-vl"  # 百度多模态模型

# 初始化百度AI客户端（兼容OpenAI格式）
client = OpenAI(
    api_key=BAIDU_API_KEY,
    base_url=BAIDU_BASE_URL,
)


# --- 2. 核心功能函数（文心一言4.5深度调用）---
def handle_electric_consult(question: str) -> dict:
    """功能1：智能用电咨询（解答电费、电价、业务办理等问题）"""
    prompt = f"""
你是中国国家电网的资深用电咨询专家，需用通俗语言解答居民用户问题，要求：
1. 准确性：严格依据国家电网现行政策（如居民电价标准、业务办理流程）；
2. 实用性：直接给出解决方案或步骤，避免冗余；
3. 完整性：若问题涉及办理材料/流程，需列出关键要点。

用户问题：{question}

请按「问题解答+补充提示」结构回复，例如：
【问题解答】您咨询的"电费查询方式"有3种：1. 登录"网上国网"APP→首页"电费查询"；2. 拨打95598热线；3. 前往线下营业厅。
【补充提示】建议绑定APP接收电费账单推送，避免逾期。
"""
    try:
        completion = client.chat.completions.create(
            model=MODEL_NAME,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.3,  # 低温度确保政策准确性
            stream=False,
        )
        return {"success": True, "result": completion.choices[0].message.content}
    except Exception as e:
        return {"success": False, "error": f"咨询失败：{str(e)}"}


def handle_fault_guide(
    fault_desc: str,
    has_power: Optional[str] = "未知",
    is_neighbor_ok: Optional[str] = "未知",
) -> dict:
    """功能2：故障报修指引（根据现象生成排查步骤）"""
    prompt = f"""
你是中国国家电网的故障排查专家，需根据居民描述的用电故障，生成「分步排查指南」，要求：
1. 逻辑性：先判断故障范围（自家/片区），再逐步定位原因；
2. 安全性：涉及操作需提示安全注意事项（如断电操作）；
3. 落地性：最后明确是否需要报修及报修方式（95598/APP）。

故障信息：
- 故障描述：{fault_desc}
- 自家总闸是否跳闸：{has_power}（可选值：跳闸/未跳闸/未知）
- 邻居是否有电：{is_neighbor_ok}（可选值：有/没有/未知）

请按「故障范围判断→分步排查步骤→报修建议」结构回复，例如：
【故障范围判断】根据"邻居有电+自家总闸跳闸"，判断为自家线路故障。
【分步排查步骤】1. 安全提示：排查前请断开总闸，避免触电；2. 检查近期新增用电设备（如空调）是否过载；3. 逐个拔掉插座，合上总闸，若合闸成功则定位为某设备短路；4. 若仍跳闸，可能是线路老化，需联系电工。
【报修建议】若完成排查仍无法解决，无需联系国网报修（非电网责任），建议联系持证电工维修。
"""
    try:
        completion = client.chat.completions.create(
            model=MODEL_NAME,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.4,  # 平衡逻辑性与灵活性
            stream=False,
        )
        return {"success": True, "result": completion.choices[0].message.content}
    except Exception as e:
        return {"success": False, "error": f"故障分析失败：{str(e)}"}


def handle_electric_analysis(
    household_no: str,
    month: str,
    family_size: int,
    high_power_devices: Optional[str] = "",
) -> dict:
    """功能3：电费分析（模拟数据对比，定位高耗电原因）"""
    prompt = f"""
你是中国国家电网的用电分析专家，需根据居民提供的用电信息，生成「月度电费分析报告」，要求：
1. 对比性：模拟同户型/同人数家庭的平均用电量，分析差异；
2. 归因性：结合高耗电设备（如空调、电热水器）分析用量变化；
3. 建议性：针对高耗电原因给出降费建议。

用电信息：
- 户号（模拟）：{household_no}
- 分析月份：{month}
- 家庭人数：{family_size}人
- 主要高耗电设备：{high_power_devices if high_power_devices else "无明确设备"}

请按「用量对比→耗电原因分析→降费建议」结构回复，例如：
【用量对比】您家{month}用电量为450度，同户型3人家庭平均用量为320度，超出40.6%。
【耗电原因分析】1. 您提到有"2台空调+1台电热水器"，夏季空调日均耗电约8度（占总用量53%）；2. 可能存在设备待机耗电（如机顶盒、路由器长期通电）。
【降费建议】1. 空调温度设定26℃，使用睡眠模式；2. 电热水器设置保温温度50℃，避免反复加热；3. 不用时拔掉设备插头，减少待机耗电。
"""
    try:
        completion = client.chat.completions.create(
            model=MODEL_NAME,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.5,  # 允许合理模拟数据
            stream=False,
        )
        return {"success": True, "result": completion.choices[0].message.content}
    except Exception as e:
        return {"success": False, "error": f"电费分析失败：{str(e)}"}


def handle_energy_saving(
    house_type: str,
    usage_habit: Optional[str] = "",
    has_renewable: Optional[str] = "无",
) -> dict:
    """功能4：节能建议（个性化定制）"""
    prompt = f"""
你是中国国家电网的节能顾问，需根据居民家庭情况，生成「定制化节能方案」，要求：
1. 针对性：结合户型、用电习惯给出具体建议（非通用口号）；
2. 经济性：说明节能措施的预期节电率及成本回收周期（如更换LED灯）；
3. 政策契合：提及国网相关节能政策（如光伏并网补贴）。

家庭情况：
- 户型：{house_type}（如两居室、三居室）
- 用电习惯：{usage_habit if usage_habit else "无特殊习惯"}（如长期开空调、频繁使用烤箱）
- 是否有可再生能源设备：{has_renewable}（如光伏板、太阳能热水器）

请按「短期节能措施（1-3个月）→中期节能措施（6-12个月）→政策福利」结构回复，例如：
【短期节能措施】1. 更换所有照明为LED灯（10瓦替代60瓦），单灯日均节电1.2度，全屋10灯年节电438度，成本约100元，3个月回收；2. 空调设置26℃，避免开门开窗。
【中期节能措施】1. 更换一级能效冰箱（替代老旧二级），日均节电0.5度，年节电182度，成本约2000元，3年回收；2. 安装智能插座，自动切断待机设备电源。
【政策福利】若您计划安装光伏板，可通过"网上国网"APP申请并网，享受0.03元/度国家补贴（具体以当地政策为准）。
"""
    try:
        completion = client.chat.completions.create(
            model=MODEL_NAME,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.4,  # 确保建议可落地
            stream=False,
        )
        return {"success": True, "result": completion.choices[0].message.content}
    except Exception as e:
        return {"success": False, "error": f"节能建议生成失败：{str(e)}"}


# --- 3. Gradio界面包装函数（快速测试用）---
def gradio_consult(question):
    res = handle_electric_consult(question)
    return res["result"] if res["success"] else f"❌ 错误：{res['error']}"


def gradio_fault(fault_desc, has_power, is_neighbor_ok):
    res = handle_fault_guide(fault_desc, has_power, is_neighbor_ok)
    return res["result"] if res["success"] else f"❌ 错误：{res['error']}"


def gradio_analysis(household_no, month, family_size, high_power_devices):
    res = handle_electric_analysis(household_no, month, family_size, high_power_devices)
    return res["result"] if res["success"] else f"❌ 错误：{res['error']}"


def gradio_energy(house_type, usage_habit, has_renewable):
    res = handle_energy_saving(house_type, usage_habit, has_renewable)
    return res["result"] if res["success"] else f"❌ 错误：{res['error']}"


# --- 4. Gradio界面定义（多标签页，清晰分区）---
def create_gradio_interface():
    with gr.Blocks(title="国网慧电管家", theme=gr.themes.Soft()) as demo:
        gr.Markdown("# ⚡ 国网慧电管家")
        gr.Markdown(
            "基于文心一言4.5的居民用电智能服务平台，解决咨询、故障、电费、节能四大需求"
        )

        with gr.Tabs():
            # 标签1：用电咨询
            with gr.Tab("📞 用电咨询"):
                gr.Markdown("输入您的用电问题（如电费查询、电价标准、业务办理）")
                question = gr.Textbox(
                    label="您的问题",
                    placeholder="例如：怎么查询上个月的电费？居民电价是多少？",
                )
                consult_btn = gr.Button("获取解答", variant="primary")
                consult_output = gr.Markdown(label="解答结果")
                consult_btn.click(
                    gradio_consult, inputs=question, outputs=consult_output
                )

            # 标签2：故障指引
            with gr.Tab("🔧 故障报修指引"):
                gr.Markdown("描述您的用电故障，获取分步排查方案")
                with gr.Row():
                    fault_desc = gr.Textbox(
                        label="故障描述",
                        placeholder="例如：家里突然没电，灯不亮，插座没反应",
                    )
                with gr.Row():
                    has_power = gr.Dropdown(
                        label="自家总闸是否跳闸",
                        choices=["未知", "跳闸", "未跳闸"],
                        value="未知",
                    )
                    is_neighbor_ok = gr.Dropdown(
                        label="邻居是否有电",
                        choices=["未知", "有", "没有"],
                        value="未知",
                    )
                fault_btn = gr.Button("生成排查指南", variant="primary")
                fault_output = gr.Markdown(label="排查结果")
                fault_btn.click(
                    gradio_fault,
                    inputs=[fault_desc, has_power, is_neighbor_ok],
                    outputs=fault_output,
                )

            # 标签3：电费分析
            with gr.Tab("📊 电费分析"):
                gr.Markdown("输入用电信息，获取用量对比及降费建议（模拟数据）")
                with gr.Row():
                    household_no = gr.Textbox(
                        label="户号（模拟）", placeholder="例如：1001234567"
                    )
                    month = gr.Textbox(label="分析月份", placeholder="例如：2024年8月")
                with gr.Row():
                    family_size = gr.Number(label="家庭人数", value=3, minimum=1)
                    high_power_devices = gr.Textbox(
                        label="高耗电设备", placeholder="例如：2台空调、1台电热水器"
                    )
                analysis_btn = gr.Button("生成分析报告", variant="primary")
                analysis_output = gr.Markdown(label="分析结果")
                analysis_btn.click(
                    gradio_analysis,
                    inputs=[household_no, month, family_size, high_power_devices],
                    outputs=analysis_output,
                )

            # 标签4：节能建议
            with gr.Tab("🌱 节能建议"):
                gr.Markdown("输入家庭情况，获取定制化节能方案")
                house_type = gr.Dropdown(
                    label="户型",
                    choices=["一居室", "两居室", "三居室", "四居室及以上"],
                    value="两居室",
                )
                usage_habit = gr.Textbox(
                    label="用电习惯",
                    placeholder="例如：长期开空调、频繁使用烤箱、晚上10点后用电多",
                )
                has_renewable = gr.Dropdown(
                    label="是否有可再生能源设备",
                    choices=["无", "光伏板", "太阳能热水器"],
                    value="无",
                )
                energy_btn = gr.Button("生成节能方案", variant="primary")
                energy_output = gr.Markdown(label="节能结果")
                energy_btn.click(
                    gradio_energy,
                    inputs=[house_type, usage_habit, has_renewable],
                    outputs=energy_output,
                )

    return demo


# --- 5. FastAPI应用定义（提供API接口，支持前端对接）---
app = FastAPI(title="国网慧电管家API", description="居民用电智能服务接口")


# 请求模型定义（Pydantic验证输入）
class ConsultRequest(BaseModel):
    question: str


class FaultRequest(BaseModel):
    fault_desc: str
    has_power: Optional[str] = "未知"
    is_neighbor_ok: Optional[str] = "未知"


class AnalysisRequest(BaseModel):
    household_no: str
    month: str
    family_size: int
    high_power_devices: Optional[str] = ""


class EnergyRequest(BaseModel):
    house_type: str
    usage_habit: Optional[str] = ""
    has_renewable: Optional[str] = "无"


# API端点定义
@app.post("/api/consult", summary="用电咨询接口")
async def api_consult(req: ConsultRequest):
    res = handle_electric_consult(req.question)
    if res["success"]:
        return res
    raise HTTPException(status_code=500, detail=res["error"])


@app.post("/api/fault", summary="故障指引接口")
async def api_fault(req: FaultRequest):
    res = handle_fault_guide(req.fault_desc, req.has_power, req.is_neighbor_ok)
    if res["success"]:
        return res
    raise HTTPException(status_code=500, detail=res["error"])


@app.post("/api/analysis", summary="电费分析接口")
async def api_analysis(req: AnalysisRequest):
    res = handle_electric_analysis(
        req.household_no, req.month, req.family_size, req.high_power_devices
    )
    if res["success"]:
        return res
    raise HTTPException(status_code=500, detail=res["error"])


@app.post("/api/energy", summary="节能建议接口")
async def api_energy(req: EnergyRequest):
    res = handle_electric_saving(req.house_type, req.usage_habit, req.has_renewable)
    if res["success"]:
        return res
    raise HTTPException(status_code=500, detail=res["error"])


# 健康检查接口
@app.get("/health", summary="服务健康检查")
async def health_check():
    return {"status": "healthy", "service": "国网慧电管家"}


# --- 6. 应用启动逻辑（整合Gradio与FastAPI）---
if __name__ == "__main__":
    # 挂载Gradio界面到FastAPI根路径
    gradio_demo = create_gradio_interface()
    app = gr.mount_gradio_app(app, gradio_demo, path="/")

    # 启动服务
    print("🚀 国网慧电管家服务启动成功！")
    print("📱 Gradio测试界面：http://localhost:7860")
    print("💻 API文档地址：http://localhost:7860/docs")
    uvicorn.run(app, host="0.0.0.0", port=7860)
